package com.yingdong.logic.service;

import static java.lang.Thread.sleep;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import com.yingdong.annotation.AutoInvoke;
import com.yingdong.db.Account;
import com.yingdong.db.User;
import com.yingdong.gateserver.innter.service.ConfigService;
import com.yingdong.handler.LogOffHandler;
import com.yingdong.logic.domain.GameUser;
import com.yingdong.logic.domain.QueueLoginInfo;
import com.yingdong.message.DisconnectMessage;
import com.yingdong.message.LoginOkMessage;
import com.yingdong.sceneserver.net.GameUserSession;
import com.yingdong.sceneserver.opcode.Dispatcher;

@Service
public class SceneThreadService {
	static Log logger = LogFactory.getLog(SceneThreadService.class);
	public static ExecutorService gameThreadPool = Executors.newFixedThreadPool(10);
	public static Thread saveGamePlayerThread;
	public static Thread updateCreaturesThread;
	public static Thread gameTimerThread;
	public static Thread loginThread;
	public static Thread heartBeatThread;

	@AutoInvoke
	public static void init() {
		heartBeatThread = new Thread(new Runnable() {
			int t = ConfigService.getPropertyInt("server.login.queue.sleep");

			public void run() {
				while (true) {
					try {
						for (GameUserSession session : Dispatcher.sessionMap.values()) {
							if (session.getLastHeartBeatTimestamp() != 0) {
								if (System.currentTimeMillis() - session.getLastHeartBeatTimestamp() > ConfigService.getPropertyInt("game.timeout")) {
									new DisconnectMessage().sendToClient(session.getSessionId());
									LogOffHandler.handleLogoff(session, null);
								}
							}
						}

						Thread.sleep(30 * 1000);
					} catch (InterruptedException e) {
						logger.info("", e);
					}
				}
			}
		});
		heartBeatThread.setName("HeartBeatThread");
		heartBeatThread.start();
		loginThread = new Thread(new Runnable() {
			public void run() {
				int t = ConfigService.getPropertyInt("server.login.queue.sleep");
				while (true) {
					try {
						QueueLoginInfo info = OnlineService.loginQueue.take();
						GameUserSession session = info.getSession();
						String userName = info.getAccName();
						String password = info.getPassword();
						if (session.isAlive()) {
							if (session.getContext().containsKey("accId")) {
								int accId = (Integer) session.getContext().get("accId");
								GameUser user = OnlineService.getGameUserByAccId(accId);
								if (user != null) {
									new DisconnectMessage().sendToClient(user.getSessionId());
									return;
								}
							}
							SceneThreadService.gameThreadPool.execute(new Runnable() {
								public void run() {
									try {
										if (!session.isAlive()) {
											return;
										}
										List<Account> list = Account.getInstance().selectObjectsByCondition("accName", userName);
										if (list.size() == 0) {
											Account account = new Account();
											account.setAccName(userName);
											account.setPassword(password);
											account.setCreateDttm((int) (System.currentTimeMillis() / 1000));
											Object index = account.saveToDB();
											account.setId((Integer) index);
											synchronized (session) {
												if (!session.isAlive()) {
													return;
												}
												session.getContext().put("accId", account.getId());
												new LoginOkMessage(1, account.getId(), 0).sendToClient(session.getSessionId());
											}
										} else if (list.size() == 1) {
											List<User> ulist = User.getInstance().selectObjectsByCondition("accId", list.get(0).getId());
											synchronized (session) {
												if (!session.isAlive()) {
													return;
												}
												if (ulist.size() > 0)
													new LoginOkMessage(1, list.get(0).getId(), ulist.get(0).getId()).sendToClient(session.getSessionId());
												else {
													new LoginOkMessage(1, list.get(0).getId(), 0).sendToClient(session.getSessionId());
												}
											}
										} else {
											new LoginOkMessage(2, 0, 0).sendToClient(session.getSessionId());
										}
										session.setActive(true);
									} finally {
										session.setHandle(true);
									}
								}
							});
							sleep(t);
						}
					} catch (Exception e) {
						logger.info("", e);
					}
				}
			}
		});
		loginThread.setName("LoginThread");
		loginThread.start();
		// final ConcurrentLinkedQueue<GameTimer> ts = TimerService.timers;

		// 游戏主体刷新线程
		gameTimerThread = new Thread(new Runnable() {
			private long lastTime = System.currentTimeMillis(), curTime;
			private int timeDelt;

			@Override
			public void run() {
				while (true) {
					try {
						curTime = System.currentTimeMillis();
						timeDelt = (int) (curTime - lastTime);
						lastTime = curTime;
						OnlineService.update(timeDelt);
						sleep(1000);

					} catch (Exception e) {
						logger.error("", e);
					} finally {
						// DatabaseFactory.closeSession();

					}
				}

			}
		});

		gameTimerThread.setName("GameTimerThread");
		gameTimerThread.start();

		// 生物刷新线程
		updateCreaturesThread = new Thread(new Runnable() {
			private long lastTime = System.currentTimeMillis(), curTime;
			private int timeDelt;

			// private Collection<Creature> collection;

			@Override
			public void run() {
				while (true) {
					try {
						curTime = System.currentTimeMillis();
						timeDelt = (int) (curTime - lastTime);
						lastTime = curTime;
						// for (GamePlayer gamPlayer :
						// OnlineGameService.userOnlineMap.values()) {
						// gamPlayer.onUpdate();
						// }
						sleep(1000);

					} catch (Exception e) {
						logger.error("", e);
						// LoggerService.trace(e.getMessage());
					} finally {
						// DatabaseFactory.closeSession();
					}
				}
			}
		});
		updateCreaturesThread.setName("UpdateCreaturesThread");
		updateCreaturesThread.start();

		saveGamePlayerThread = new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						OnlineService.save();

						sleep(10 * 60 * 1000);

					} catch (Exception e) {
						logger.error("", e);
					}

					finally {

					}
				}

			}
		});
		saveGamePlayerThread.setName("SaveGamePlayerThread");
		saveGamePlayerThread.start();
		logger.info("SceneThreadService加载完毕");
	}

}
